<template>
  <div ref="card" class="card-hover-effect">
    <slot></slot>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';
import gsap from 'gsap';

const card = ref<HTMLElement | null>(null);

let scene: THREE.Scene;
let camera: THREE.PerspectiveCamera;
let renderer: THREE.WebGLRenderer;
let geometry: THREE.BoxGeometry;
let material: THREE.MeshStandardMaterial;
let mesh: THREE.Mesh;
let mouse = new THREE.Vector2(0.5, 0.5);
let targetRotation = new THREE.Vector2(0, 0);

const onMouseMove = (event: MouseEvent) => {
  if (card.value) {
    const rect = card.value.getBoundingClientRect();
    mouse.x = (event.clientX - rect.left) / rect.width;
    mouse.y = (event.clientY - rect.top) / rect.height;
  }
};

const onMouseLeave = () => {
  gsap.to(targetRotation, {
    x: 0,
    y: 0,
    duration: 1,
    ease: 'power3.out',
  });
};

const init = () => {
  if (!card.value) return;

  // Scene
  scene = new THREE.Scene();

  // Camera
  camera = new THREE.PerspectiveCamera(75, card.value.offsetWidth / card.value.offsetHeight, 0.1, 1000);
  camera.position.z = 2;

  // Renderer
  renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
  renderer.setSize(card.value.offsetWidth, card.value.offsetHeight);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  card.value.appendChild(renderer.domElement);

  // Geometry and Material
  geometry = new THREE.BoxGeometry(1.5, 1, 0.1);
  material = new THREE.MeshStandardMaterial({
    color: 0xffffff,
    metalness: 0.7,
    roughness: 0.3,
    transparent: true,
    opacity: 0.1
  });

  // Mesh
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  // Lights
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);

  const pointLight = new THREE.PointLight(0xffffff, 0.8);
  pointLight.position.set(2, 3, 4);
  scene.add(pointLight);

  // Event Listeners
  card.value.addEventListener('mousemove', onMouseMove);
  card.value.addEventListener('mouseleave', onMouseLeave);

  animate();
};

const animate = () => {
  requestAnimationFrame(animate);

  // Update target rotation based on mouse position
  targetRotation.y = (mouse.x - 0.5) * 0.5;
  targetRotation.x = (mouse.y - 0.5) * 0.5;

  // Smoothly interpolate current rotation to target rotation
  mesh.rotation.x += (targetRotation.x - mesh.rotation.x) * 0.05;
  mesh.rotation.y += (targetRotation.y - mesh.rotation.y) * 0.05;

  renderer.render(scene, camera);
};

onMounted(() => {
  // We need to wait for the component to be mounted to get the correct dimensions
  // Using a small timeout to ensure the DOM is ready
  setTimeout(init, 100);
});

onUnmounted(() => {
  if (card.value) {
    card.value.removeEventListener('mousemove', onMouseMove);
    card.value.removeEventListener('mouseleave', onMouseLeave);
  }
  if (renderer) {
    renderer.dispose();
  }
});
</script>

<style scoped>
.card-hover-effect {
  position: relative;
  overflow: hidden;
}
:deep(canvas) {
  position: absolute;
  top: 0;
  left: 0;
  width: 100% !important;
  height: 100% !important;
  pointer-events: none;
}
</style>